package com.tyros.common.kit.bean;

import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Unchecked Cast 工具类
 *
 * @author zhangshuaiyin
 * @date 2022/3/3 16:26
 */
@SuppressWarnings("unused")
public class GenericsKit {

    /**
     * 转 List
     *
     * @param obj 转化前对象
     * @return 转化后对象
     */
    public static List<?> castList(Object obj) {
        List<?> list = null;
        if (obj instanceof List<?>) {
            list = (List<?>) obj;
        }
        return list;
    }

    /**
     * 转 List<T>
     *
     * @param obj   转化前对象
     * @param clazz 泛型类型
     * @param <T>   泛型
     * @return 转化后对象
     */
    public static <T> List<T> castList(Object obj, Class<T> clazz) {
        List<T> result = new ArrayList<>();
        if (obj instanceof List<?>) {
            for (Object o : (List<?>) obj) {
                result.add(clazz.cast(o));
            }
            return result;
        }
        return null;
    }

    /**
     * 转 Map
     *
     * @param obj 转化前对象
     * @return 转化后对象
     */
    public static Map<?, ?> castMap(Object obj) {
        Map<?, ?> map = null;
        if (obj instanceof Map<?, ?>) {
            map = (Map<?, ?>) obj;
        }
        return map;
    }

    /**
     * 转 Map<K, V>
     *
     * @param obj    转化前对象
     * @param kClass Key 泛型类型
     * @param vClass Value 泛型类型
     * @param <K>    Key 泛型
     * @param <V>    Value 泛型
     * @return 转化后对象
     */
    public static <K, V> Map<K, V> castMap(Object obj, Class<K> kClass, Class<V> vClass) {
        Map<K, V> map = new HashMap<>(16);
        if (obj instanceof Map<?, ?>) {
            ((Map<?, ?>) obj).forEach((k, v) -> map.put(kClass.cast(k), vClass.cast(v)));
            return map;
        }
        return null;
    }

    /**
     * 转 List<Map>
     *
     * @param obj 转化前对象
     * @return 转化后对象
     */
    public static List<Map<?, ?>> castListMap(Object obj) {
        List<Map<?, ?>> list = new ArrayList<>();
        if (obj instanceof List<?>) {
            for (Object map : (List<?>) obj) {
                if (map instanceof Map<?, ?>) {
                    list.add(castMap(map));
                }
            }
            return list;
        }
        return null;
    }

    /**
     * 转 List<Map<K, V>>
     *
     * @param obj    转化前对象
     * @param kClass Key 泛型类型
     * @param vClass Value 泛型类型
     * @param <K>    Key 泛型
     * @param <V>    Value 泛型
     * @return 转化后对象
     */
    public static <K, V> List<Map<K, V>> castListMap(Object obj, Class<K> kClass, Class<V> vClass) {
        List<Map<K, V>> list = new ArrayList<>();
        if (obj instanceof List<?>) {
            for (Object map : (List<?>) obj) {
                if (map instanceof Map<?, ?>) {
                    list.add(castMap(map, kClass, vClass));
                }
            }
            return list;
        }
        return null;
    }

    /**
     * Object 转 T
     *
     * @param returnClass 泛型类型
     * @param obj       转化前对象
     * @param <T>         泛型对象
     * @return 转化后对象
     */
    public static <T> T castObject(Object obj, Class<T> returnClass) {
        if (obj.getClass().equals(returnClass)) {
            ObjectMapper objectMapper = new ObjectMapper();
            return objectMapper.convertValue(obj, returnClass);
        }
        return null;
    }
}
